<script setup lang="ts">
import { IBox } from "./inter"
import { ref, computed, unref, watch, toRefs,onMounted } from "vue"
import { useElementSize, useScroll, useMouse, useMousePressed,useParentElement  } from "@vueuse/core"

const props = withDefaults(defineProps<IBox.ScrollProps>(), {
  minSize: 40,
})

const { minSize, thumbClass } = props;
const { x: px, y: py } = toRefs(props)

const boxRef = ref<HTMLDivElement>();
const wrapperRef = ref<HTMLDivElement>();
const contentRef = ref<HTMLDivElement>();
const thumbYRef = ref<HTMLDivElement>();
const thumbXRef = ref<HTMLDivElement>();
const parentEl = useParentElement();
//
const { x: mx, y: my } = useMouse({ target: parentEl })
const { x, y } = useScroll(wrapperRef)
// 计算滚动条 size 水平和垂直
const { width: bw, height: bh } = useElementSize(wrapperRef);
const { width: ew, height: eh } = useElementSize(contentRef);
// 可滑动距离 滑块大小计算 滑动距离和页面距离比例 滑动 1px => 页面滚动多少 px 
const dx = computed(() => unref(ew) - unref(bw))
const dy = computed(() => unref(eh) - unref(bh))
// 
const xSize = computed(() => {
  const bs = unref(bw);
  const d = unref(dx);
  const m = minSize < bs ? minSize : bs * 0.5
  if (d >= bs - m) {
    return m;
  }
  return bs - d;
})
const ySize = computed(() => {
  const bs = unref(bh);
  const m = minSize < bs ? minSize : bs * 0.5
  const d = unref(dy);
  if (d >= bs - m) {
    return m;
  }
  return bs - d;
})
const de = computed(() => (unref(dx) > 0 && unref(dy) > 0) ? 10 : 0)
// 水平比例
const sx = computed(() => unref(dx) / (unref(bw) - unref(xSize) - unref(de)))
const sy = computed(() => unref(dy) / (unref(bh) - unref(ySize) - unref(de)))
// 位置映射
// 滑块位置
const tx = computed(() => unref(x) / unref(sx))
const ty = computed(() => unref(y) / unref(sy))
// 是否显示滚动条
const showX = computed(() => unref(dx) > 0)
const showY = computed(() => unref(dy) > 0)
//
let cs: any = -1;
//
const { pressed: xp } = useMousePressed({ target: thumbXRef })
watch(xp, (v) => unref(showX) && (v ? cs = unref(x) - unref(mx) * unref(sx) : cs = -1));
watch(mx, (v) => {
  if (unref(showX) && unref(xp)) {
    const t = cs + v * unref(sx);
    x.value = t >= unref(dx) ? unref(dx) : t;
    // console.log('xxxx ==== ',t, dy.value, x.value, v, unref(sx), cs, v * unref(sy))
  }
})
watch(px, (v = 0) => { x.value = v >= unref(dx) ? unref(dx) : v > 0 ? v : 0 })
//
const { pressed: yp } = useMousePressed({ target: thumbYRef })
watch(yp, (v) => unref(showY) && (v ? (cs = unref(y) - unref(my) * unref(sy)) : cs = -1));
watch(my, (v) => {
  if (unref(yp)) {
    const t = cs + v * unref(sy);
    y.value = t >= unref(dy) ? unref(dy) : t;
  }
})
watch(py, (v = 0) => { y.value = v >= unref(dy) ? unref(dy) : v > 0 ? v : 0 })

// 点击滑轨 计算页面滚动值
const handleClick = (e:MouseEvent,xy:"x"|"y") => {
  const {offsetX,offsetY} = e;
  const d = xy == 'x' ? unref(dx) : unref(dy);
  const s = xy == 'x' ? offsetX : offsetY;
  const p = xy == 'x' ? unref(sx) : unref(sy);
  const t = s - minSize / 2;
  const v = t * p;
  const val = v < 0 ? 0 : v > d ? d : v;
  if(xy == 'x'){x.value = val}
  else {y.value = val}
}
// 初始化 定位
onMounted(() => {
  if(unref(px) || unref(py)){
    resetScroll(unref(px),unref(py))
  }
})

//
const resetScroll = (px = -1, py = -1) => {
  if (px > 0 && unref(x) < unref(dx)) {
    x.value = px;
  }
  if (py > 0 && unref(y) < unref(dy)) {
    // 如果不设定 延时 会导致只有 y 轴进行了滚动，x 轴 不会滚动
    setTimeout(() => y.value = py,0)
    // y.value = py
    
  }
}
defineExpose({ resetScroll,x,y })

</script>

<template>
  <div ref="boxRef" :class="['box-scroll',{'is-animate':!xp && !yp}]" relative w-full h-full box-border b-none text-0 overflow-hidden>
    <!-- 内容区 -->
    <div ref="wrapperRef" :class="['_wrapper',{'overflow-y-hidden':xp,'overflow-x-hidden':yp}]" relative w-full h-full overflow-auto lh-0>
      <div ref="contentRef" inline-block min-w-full min-h-full>
        <slot></slot>
      </div>
    </div>
    <!-- 竖向滚动条 -->
    <div v-if="showY" absolute top-0 right-0 w-10 h-full z-99 class="_scroll-bar _vertical" @click.stop="(e) => handleClick(e,'y')">
      <div ref="thumbYRef" :class="['_thumb', thumbClass, { 'is-pressed': yp }]" absolute w-full text-12 rd-12
        :style="`height:${ySize}px;top:${ty}px;`" @click.stop=""></div>
    </div>
    <!-- 横向滚动条 -->
    <div v-if="showX" absolute left-0 bottom-0 h-10 w-full z-99 class="_scroll-bar _horizontal" @click.stop="(e) => handleClick(e,'x')">
      <div ref="thumbXRef" :class="['_thumb', thumbClass, { 'is-pressed': xp }]" absolute h-full text-12 rd-12
        :style="`width:${xSize}px;left:${tx}px;`" @click.stop=""></div>
    </div>
    <div v-if="showX && showY" absolute w-10 h-10 bottom-0 right-0 z-99 @click.stop="() => resetScroll(dx,dy)"></div>
  </div>
</template> 


<style scoped>
.box-scroll {
  ._wrapper::-webkit-scrollbar {
    width: 0px !important;
    height: 0px !important;
  }

  ._wrapper::-webkit-scrollbar-track {
    width: 0;
    height: 0;
  }

  ._thumb {
    opacity: .2;
    background-color: #00000088;

    &.is-pressed {
      opacity: 1;
    }
  }
  ._scroll-bar{
    &:hover{
      background-color:#00000044;
    }
  }
  &:hover {
    ._thumb {
      opacity: 1;
    }
  }

  &.is-animate{
    ._wrapper{
      scroll-behavior: smooth;
    }
  }
}
</style>